package net.jcip.examples.chapter7;

import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;

/**
 * 这段代码定义了一个名为 `ReaderThread` 的线程类，它从一个套接字的输入流中读取数据并处理数据。以下是对代码的详细分析：
 *
 * ### 类成员和构造函数
 *
 * ```java
 * public class ReaderThread extends Thread {
 *     private static final int BUFSZ = 512; // 缓冲区大小
 *     private final Socket socket; // 套接字，用于通信
 *     private final InputStream in; // 输入流，从套接字读取数据
 *
 *     // 构造函数，接收一个 Socket 对象并获取其输入流
 *     public ReaderThread(Socket socket) throws IOException {
 *         this.socket = socket;
 *         this.in = socket.getInputStream();
 *     }
 * ```
 *
 * - `BUFSZ` 是缓冲区大小，用于存储从套接字读取的数据。
 * - `socket` 是一个套接字对象，通过它进行网络通信。
 * - `in` 是从套接字获取的输入流，用于读取数据。
 *
 * ### `interrupt` 方法
 *
 * ```java
 *     @Override
 *     public void interrupt() {
 *         try {
 *             socket.close(); // 关闭套接字，触发正在进行的读取操作抛出异常
 *         } catch (IOException ignored) {
 *         } finally {
 *             super.interrupt(); // 调用父类的 interrupt 方法中断线程
 *         }
 *     }
 * ```
 *
 * - 重写 `interrupt` 方法，通过关闭套接字来中断正在进行的读取操作。
 * - `socket.close()` 会触发正在进行的 `in.read()` 操作抛出 `IOException`，使线程可以在 catch 块中退出。
 * - 调用父类的 `interrupt` 方法，确保线程被中断。
 *
 * ### `run` 方法
 *
 * ```java
 *     @Override
 *     public void run() {
 *         try {
 *             byte[] buf = new byte[BUFSZ]; // 创建缓冲区
 *             while (true) {
 *                 int count = in.read(buf); // 从输入流读取数据到缓冲区
 *                 if (count < 0) // 读取到流的末尾，退出循环
 *                     break;
 *                 else if (count > 0) // 读取到数据，处理数据
 *                     processBuffer(buf, count);
 *             }
 *         } catch (IOException e) {
 *             // 读取过程中发生 IOException，线程允许退出
 *         }
 *     }
 * ```
 *
 * - 创建一个缓冲区 `buf`，大小为 `BUFSZ`。
 * - 进入无限循环，从输入流中读取数据到缓冲区。
 *   - `in.read(buf)` 返回读取的字节数，如果返回值为 -1，表示流的末尾，退出循环。
 *   - 如果读取到数据（`count > 0`），调用 `processBuffer` 方法处理数据。
 *
 * ### `processBuffer` 方法
 *
 * ```java
 *     public void processBuffer(byte[] buf, int count) {
 *         // 处理缓冲区中的数据，这里是一个空方法，需要在子类或调用处实现具体的处理逻辑
 *     }
 * }
 * ```
 *
 * - `processBuffer` 方法是一个占位方法，用于处理读取到的缓冲区数据。
 * - 需要在子类或实例中实现具体的处理逻辑。
 *
 * ### 总结
 *
 * - `ReaderThread` 类扩展了 `Thread` 类，专门用于从网络套接字读取数据。
 * - 通过重写 `interrupt` 方法，可以优雅地中断线程。
 * - 在 `run` 方法中，通过循环读取数据并调用 `processBuffer` 方法处理数据。
 * - `processBuffer` 方法是一个钩子方法，需要具体实现数据处理逻辑。
 *
 * 这段代码提供了一个良好的基础，适用于需要从网络套接字异步读取数据并进行处理的场景。
 */
public class ReaderThread extends Thread {
    private static final int BUFSZ = 512;
    private final Socket socket;
    private final InputStream in;

    public ReaderThread(Socket socket) throws IOException {
        this.socket = socket;
        this.in = socket.getInputStream();
    }

    public void interrupt() {
        try {
            socket.close();
        } catch (IOException ignored) {
        } finally {
            super.interrupt();
        }
    }

    public void run() {
        try {
            byte[] buf = new byte[BUFSZ];
            while (true) {
                int count = in.read(buf);
                if (count < 0)
                    break;
                else if (count > 0)
                    processBuffer(buf, count);
            }
        } catch (IOException e) { /* Allow thread to exit */
        }
    }

    public void processBuffer(byte[] buf, int count) {
    }
}
